/************************************************************************
*************************************************************************
Standard Program
************************************************************************
************************************************************************/



/************************************************************************
Program: ar_dem
Purpose: Estimates the AR method, demeaning first
************************************************************************/
cap program drop ar_dem
program ar_dem
	preserve
	tempvar tmp
	foreach var of varlist y k l m kXk lXl mXm kXl kXm lXm {
		egen `tmp' = mean(`var')
		replace `var' = `var'-`tmp'
		drop `tmp'
	}
	
	#delimit;
	cap gmm (y - {bk}*k - {bl}*l - {bm}*m - {bkk}*kXk - {bll}*lXl - {bmm}*mXm - {bkl}*kXl - {bkm}*kXm - {blm}*lXm 
								- {rho}*(l.y - {bk}*l.k - {bl}*l.l - {bm}*l.m - {bkk}*l.kXk - {bll}*l.lXl - {bmm}*l.mXm - {bkl}*l.kXl - {bkm}*l.kXm - {blm}*l.lXm) ), 
								instruments(l.(k l m kXk-mXm) l2.m l2.k l2.kXm) 
								deriv(/bk 	= -k 	+ {rho}*l.k) 
								deriv(/bl 	= -l 	+ {rho}*l.l)
								deriv(/bm 	= -m 	+ {rho}*l.m)
								deriv(/bkk 	= -kXk 	+ {rho}*l.kXk)
								deriv(/bll 	= -lXl 	+ {rho}*l.lXl)
								deriv(/bmm 	= -mXm 	+ {rho}*l.mXm)
								deriv(/bkl 	= -kXl 	+ {rho}*l.kXl)
								deriv(/bkm 	= -kXm 	+ {rho}*l.kXm)
								deriv(/blm 	= -lXm 	+ {rho}*l.lXm)
								deriv(/rho 	= -(l.y - {bk}*l.k - {bl}*l.l - {bm}*l.m - {bkk}*l.kXk - {bll}*l.lXl - {bmm}*l.mXm - {bkl}*l.kXl - {bkm}*l.kXm - {blm}*l.lXm) ) ;
	#delimit cr
	
	restore

end




/************************************************************************
Program: ar_dem_wrap
Purpose: A wrapper for the ar_dem program (for use in bootstrapping)
************************************************************************/
cap program drop ar_dem_wrap
program ar_dem_wrap
	args spec laginst
	
	ar_dem
	if _rc == 0 {
		gen elasm_ar_dem = _b[/bm] + 2*_b[/bmm]*m + _b[/bkm]*k + _b[/blm]*l
		gen elask_ar_dem = _b[/bk] + 2*_b[/bkk]*k + _b[/bkm]*m + _b[/bkl]*l
		gen elasl_ar_dem = _b[/bl] + 2*_b[/bll]*l + _b[/blm]*m + _b[/bkl]*k
		gen ar_ar_dem	 = _b[/rho]
	}
	else {
		gen elasm_ar_dem = .
		gen elask_ar_dem = .
		gen elasl_ar_dem = .
		gen ar_ar_dem	 = .
	}



end	





/************************************************************************
*************************************************************************
Modified Instruments
************************************************************************
************************************************************************/

/************************************************************************
Program: ar_dem_modinst
Purpose: Estimates the AR method, demeaning first; lets wrapper specify instruments
************************************************************************/
cap program drop ar_dem_modinst
program ar_dem_modinst
	args dlaginst

	preserve
	tempvar tmp
	foreach var of varlist y k l m kXk lXl mXm kXl kXm lXm {
		egen `tmp' = mean(`var')
		replace `var' = `var'-`tmp'
		drop `tmp'
	}
	

	#delimit;
	cap gmm (y - {bk}*k - {bl}*l - {bm}*m - {bkk}*kXk - {bll}*lXl - {bmm}*mXm - {bkl}*kXl - {bkm}*kXm - {blm}*lXm 
								- {rho}*(l.y - {bk}*l.k - {bl}*l.l - {bm}*l.m - {bkk}*l.kXk - {bll}*l.lXl - {bmm}*l.mXm - {bkl}*l.kXl - {bkm}*l.kXm - {blm}*l.lXm) ), 
								instruments(l.(k l m kXk-mXm) `dlaginst' ) 
								deriv(/bk 	= -k 	+ {rho}*l.k) 
								deriv(/bl 	= -l 	+ {rho}*l.l)
								deriv(/bm 	= -m 	+ {rho}*l.m)
								deriv(/bkk 	= -kXk 	+ {rho}*l.kXk)
								deriv(/bll 	= -lXl 	+ {rho}*l.lXl)
								deriv(/bmm 	= -mXm 	+ {rho}*l.mXm)
								deriv(/bkl 	= -kXl 	+ {rho}*l.kXl)
								deriv(/bkm 	= -kXm 	+ {rho}*l.kXm)
								deriv(/blm 	= -lXm 	+ {rho}*l.lXm)
								deriv(/rho 	= -(l.y - {bk}*l.k - {bl}*l.l - {bm}*l.m - {bkk}*l.kXk - {bll}*l.lXl - {bmm}*l.mXm - {bkl}*l.kXl - {bkm}*l.kXm - {blm}*l.lXm) ) ;
	#delimit cr
	
	restore

end


cap program drop ar_dem_wrap_instnum
program ar_dem_wrap_instnum
	args spec instnum
	
	local ilist
	local count 0
	foreach term in l2.m l2.k l2.kXm l2.l l2.lXm l2.kXl {
		local ++count
		
		local ilist `ilist' `term'
		local dlaglist`count' `ilist'

	}
	
	ar_dem_modinst "`dlaglist`instnum''"
	if _rc == 0 {
		gen elasm_ar_dem`instnum' = _b[/bm] + 2*_b[/bmm]*m + _b[/bkm]*k + _b[/blm]*l
		gen elask_ar_dem`instnum' = _b[/bk] + 2*_b[/bkk]*k + _b[/bkm]*m + _b[/bkl]*l
		gen elasl_ar_dem`instnum' = _b[/bl] + 2*_b[/bll]*l + _b[/blm]*m + _b[/bkl]*k
		gen ar_ar_dem`instnum'	 = _b[/rho]
	}
	else {
		gen elasm_ar_dem`instnum' = .
		gen elask_ar_dem`instnum' = .
		gen elasl_ar_dem`instnum' = .
		gen ar_ar_dem`instnum'	 = .
	}



end	





/************************************************************************
*************************************************************************
Selection Program
************************************************************************
************************************************************************/


/************************************************************************
Program: ar_dem_select_wrap
Purpose: A wrapper for the ar_dem_select program
************************************************************************/
cap program drop ar_dem_select_wrap
program ar_dem_select_wrap
	ereturn clear
	ar_dem_select

	if e(model) == "full" {
		gen elasm_ar_dem_sel 	= _b[/bm] + 2*_b[/bmm]*m + _b[/bkm]*k + _b[/blm]*l
		gen elask_ar_dem_sel 	= _b[/bk] + 2*_b[/bkk]*k + _b[/bkm]*m + _b[/bkl]*l
		gen elasl_ar_dem_sel 	= _b[/bl] + 2*_b[/bll]*l + _b[/blm]*m + _b[/bkl]*k
		gen ar_ar_dem_sel	 	= _b[/rho]
		gen mod_ar_dem_sel		= 3
	}
	else if e(model) == "linm" {
		gen elasm_ar_dem_sel 	= _b[/bm] 
		gen elask_ar_dem_sel 	= _b[/bk] + 2*_b[/bkk]*k + _b[/bkl]*l
		gen elasl_ar_dem_sel 	= _b[/bl] + 2*_b[/bll]*l + _b[/bkl]*k
		gen ar_ar_dem_sel	 	= _b[/rho]
		gen mod_ar_dem_sel		= 2
	}
	else if e(model) == "linall" {
		gen elasm_ar_dem_sel 	= _b[/bm]
		gen elask_ar_dem_sel 	= _b[/bk]
		gen elasl_ar_dem_sel 	= _b[/bl]
		gen ar_ar_dem_sel	 	= _b[/rho]
		gen mod_ar_dem_sel		= 1
	}
	else {
		di "ESTIMATION FAILED OR MODEL NOT RECOGNIZED!!!"
		
		gen elasm_ar_dem_sel 	= .
		gen elask_ar_dem_sel 	= .
		gen elasl_ar_dem_sel 	= .
		gen ar_ar_dem_sel	 	= .
		gen mod_ar_dem_sel		= .
	}
	

end


/************************************************************************
Program: ar_dem_select
Purpose: Estimates the AR method, demeaning first
Selects from among the three versions below
************************************************************************/
cap program drop ar_dem_select
program ar_dem_select, eclass
	
	local bestspec full
	
	foreach spec in full linm linall {
		quietly: ar_dem_`spec'
		estimates store `spec'
		
		local bic`spec' = e(J) - e(J_df)*log( e(N) )
		
		if `bic`spec'' < `bic`bestspec'' {
			local bestspec `spec'
		}
	}
	
	
	quietly: estimates restore `bestspec'
	
	ereturn local model "`bestspec'"
	di "`bestspec' was chosen as the optimal specification (Jbic=`bic`bestspec'')"

end

/************************************************************************
Program: ar_dem_full
Purpose: Estimates the AR method, demeaning first
This version has all the parameters (up through order 2)
************************************************************************/
cap program drop ar_dem_full
program ar_dem_full
	preserve
	tempvar tmp
	foreach var of varlist y k l m kXk lXl mXm kXl kXm lXm {
		egen `tmp' = mean(`var')
		replace `var' = `var'-`tmp'
		drop `tmp'
	}
	
	#delimit;
	cap gmm (y - {bk}*k - {bl}*l - {bm}*m - {bkk}*kXk - {bll}*lXl - {bmm}*mXm - {bkl}*kXl - {bkm}*kXm - {blm}*lXm 
								- {rho}*(l.y - {bk}*l.k - {bl}*l.l - {bm}*l.m - {bkk}*l.kXk - {bll}*l.lXl - {bmm}*l.mXm - {bkl}*l.kXl - {bkm}*l.kXm - {blm}*l.lXm) ), 
								instruments(l.(k l m kXk-mXm) l2.m l2.k l2.kXm) 
								deriv(/bk 	= -k 	+ {rho}*l.k) 
								deriv(/bl 	= -l 	+ {rho}*l.l)
								deriv(/bm 	= -m 	+ {rho}*l.m)
								deriv(/bkk 	= -kXk 	+ {rho}*l.kXk)
								deriv(/bll 	= -lXl 	+ {rho}*l.lXl)
								deriv(/bmm 	= -mXm 	+ {rho}*l.mXm)
								deriv(/bkl 	= -kXl 	+ {rho}*l.kXl)
								deriv(/bkm 	= -kXm 	+ {rho}*l.kXm)
								deriv(/blm 	= -lXm 	+ {rho}*l.lXm)
								deriv(/rho 	= -(l.y - {bk}*l.k - {bl}*l.l - {bm}*l.m - {bkk}*l.kXk - {bll}*l.lXl - {bmm}*l.mXm - {bkl}*l.kXl - {bkm}*l.kXm - {blm}*l.lXm) ) 
								vce(cluster id) ;
	#delimit cr
	
	restore

end

/************************************************************************
Program: ar_dem_linm
Purpose: Estimates the AR method, demeaning first
This version is log linear in m
************************************************************************/
cap program drop ar_dem_linm
program ar_dem_linm
	preserve
	tempvar tmp
	foreach var of varlist y k l m kXk lXl  kXl  {
		egen `tmp' = mean(`var')
		replace `var' = `var'-`tmp'
		drop `tmp'
	}
	
	#delimit;
	cap gmm (y - {bk}*k - {bl}*l - {bm}*m - {bkk}*kXk - {bll}*lXl - {bkl}*kXl 
								- {rho}*(l.y - {bk}*l.k - {bl}*l.l - {bm}*l.m - {bkk}*l.kXk - {bll}*l.lXl - {bkl}*l.kXl) ), 
								instruments(l.(k l m kXk-mXm) l2.m l2.k l2.kXm) 
								deriv(/bk 	= -k 	+ {rho}*l.k) 
								deriv(/bl 	= -l 	+ {rho}*l.l)
								deriv(/bm 	= -m 	+ {rho}*l.m)
								deriv(/bkk 	= -kXk 	+ {rho}*l.kXk)
								deriv(/bll 	= -lXl 	+ {rho}*l.lXl)
								deriv(/bkl 	= -kXl 	+ {rho}*l.kXl)
								deriv(/rho 	= -(l.y - {bk}*l.k - {bl}*l.l - {bm}*l.m - {bkk}*l.kXk - {bll}*l.lXl - {bkl}*l.kXl ) ) 
								vce(cluster id) ;
	#delimit cr
	
	restore

end

/************************************************************************
Program: ar_dem_linall
Purpose: Estimates the AR method, demeaning first
This version is log linear in all inputs
************************************************************************/
cap program drop ar_dem_linall
program ar_dem_linall
	preserve
	tempvar tmp
	foreach var of varlist y k l m kXk lXl  kXl  {
		egen `tmp' = mean(`var')
		replace `var' = `var'-`tmp'
		drop `tmp'
	}
	
	#delimit;
	cap gmm (y - {bk}*k - {bl}*l - {bm}*m 
								- {rho}*(l.y - {bk}*l.k - {bl}*l.l - {bm}*l.m ) ), 
								instruments(l.(k l m kXk-mXm) l2.m l2.k l2.kXm) 
								deriv(/bk 	= -k 	+ {rho}*l.k) 
								deriv(/bl 	= -l 	+ {rho}*l.l)
								deriv(/bm 	= -m 	+ {rho}*l.m)
								deriv(/rho 	= -(l.y - {bk}*l.k - {bl}*l.l - {bm}*l.m  ) ) 
								vce(cluster id) ;
	#delimit cr
	
	restore

end
